print("helloWorld")

# 变量
# 命名规则：不能是关键字，只能是字母、数字、下划线_，不能以数字开头，大小写敏感
# python在定义一个变量的时候就需要赋初值：定义即赋值，但不需要指定类型

# 错误的命名
# 1a = 1 # 以数字开头
# a$b = 2 # 包含其他符号
# import = 3 # 以关键字命名

# 正确的
a1 = 1
b2 = 2
c_3 = 3
_d4 = 4
A1 = 1

print("a1:", a1, "A1:", A1)

# 查看Python中的关键字
import keyword

print(keyword.kwlist)

# 注释
# 这是一行注释 相当于Java中的 //
''' 一般多行常用于文档说明
成对的三个单引号表示多行注释
这是第1行注释
这是第2行注释
这是第3行注释
'''
""" 相当于Java中的 /* */
成对的三个双引号也可以表示多行注释
在Python不严格区分单双引号
"""

# print函数
# sep : 指定values之间的分隔符
# end : 指定换行符
# 按照 | 分割每一个value
print(1, 2, 3, 4, 5, 6, 7, 8, 9, sep="|", end=" # ")
# 不换行输出
print(1, 2, 3, 4, 5, 6, 7, 8, 9, sep="|")

# Python中的基本数据类型
# 5大基本数据类型：整型 int、浮点 float、字符串 str、布尔 bool、空类型 NoneType
# 基本数据类型都是不可变的
# type()方法 可以传入一个变量并返回变量的类型
# 整型 int
i = 1
print(i, type(i))

# 浮点 float
f = 1.0
print(f, type(f))

# 整型和浮点都是数值型的类型 可以用于数学运算 + - * / 等

# 字符串 str
str1 = 'a'
str2 = "efg"
print(str1, type(str1))
print(str2, type(str2))

str3 = "I love You!"
print(str3)
# 切分
splits = str3.split(" ")  # 按照指定的分隔符切分 并返回一个list
print(splits, type(splits))
# 截取 => 切片
# 可以通过 下标的方式取字符串中的字符
print(str3[0])
# [起始位置（默认0）:结束位置（默认最后一位）:步长=1]
# 左闭右开
# love
print(str3[2:6])

# 索引还支持负数索引
# -1 表示从右往左数第一位
print(str3[-1])

# 步长 表示 多少个元素取一次
print(str3[::1])
print(str3[::2])

# 长度
# Python中所有的长度同一通过 len()函数查看
print(len(str3))

# 替换
str4 = str3.replace("love", "hate")
print(str3)
print(str4)
print(str3.replace("o", "O", 1))

# 查找
print(str3.index("love"))

# 反转
print(str3[::-1])

# 去除字符串两边的隐藏字符
# \n 换行
# \t 制表符tab
# \r 回车
print(" \n\t\rabc\t\n ")
print(" \n\tabc\t\n ".strip())

# 布尔 bool
# 除了 False就是True 首字母大写
# 一般用于条件表达式
# 可以用于 逻辑运算 与 或 非 异或
bool1 = False
bool2 = True
print(bool1, bool2)

# 空类型 NoneType
# 相当于null
n = None
print(type(n), n)

# 算术运算符
# + - * / % ** //
a = 10
b = 3

print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(a % b)
print(a ** b)  # a的b次方
print(a // b)  # 向下取整 直接舍弃小数位
print(10 // 4)  #

# 算术优先级
print(2 ** 3 ** 2)  # 从后往前
print(20 // 3 // 2)  # 从前往后

# 逻辑运算符
bool1 = False
bool2 = True
print(bool1 & bool2)  # False
print(bool1 and bool2)  # False
print(bool1 | bool2)  # True
print(bool1 or bool2)  # True
print(not bool1)  # True
print(bool1 ^ bool2)  # True

# 类型转换
# 记住四个方法：int()、float()、str()、bool()
# 转换时候注意 值是否符合转换的要求
str1 = '123'
print(str1, type(str1))
# str to int
i1 = int(str1)
print(i1, type(i1))

# int to str
i2 = 456789
str2 = str(i2)
print(i2, type(i2))
print(str2, type(str2))

str3 = 'abc'
# int(str3) # ValueError 值类型不匹配

# to bool
# 对于数值型的数转bool：除0以外都是True
# 对于字符串转bool：除空字符串以外都是True
print(bool("abc"))  # True
print(bool("True"))  # True
print(bool("False"))  # True
print(bool(""))  # False
print(bool(100))  # True
print(bool(1))  # True
print(bool(0))  # False
print(bool(-0))  # False
print(bool(-1))  # True
print(bool(0.0))  # False
print(bool(1.111))  # True
print(bool(-1.11))  # True
print(bool(None))  # False

print("#" * 30)

# Python中的四大数据容器（数据结构）
# 相当于Java中的集合（collection）
# 列表list、元组tuple、字典dict、集合set

# 列表：list
# 定义： [elem1,elem2,elem3,......]
# 用法：增删改查
# 特点：可变的，有序，元素的类型可以不相同，元素可以不唯一

list1 = [1, 2, 3, 4, 5, 6, 7, 7, 7, 2]
print(list1, type(list1))

# 常见的用法
# 查 ： 获取元素
print(list1.index(2))

# 切片
# [起始位置（默认0）:结束位置（默认最后一位）:步长=1]
# 左闭右开
# 通过索引获取元素
print(list1[3])
print(list1[1:5:1])
print(list1[::-1])

# 增
list1.append(8)
print(list1)
list1.insert(1, 1.1)
print(list1)

# 改
list1[2] = '3'
print(list1)

# 删
print(list1.pop())  # 将最后一个元素取出来
list1.remove('3')
print(list1)

# 其他的方法
list2 = [2, 1, 4, 3, 8, 7, 5, 6, 9]
list2.sort()  # 升序排序
print(list2)
list2.sort(reverse=True)  # 倒序
print(list2)
list2.reverse()  # 反转
print(list2)

# 元组 tuple
# 定义：(elem1,elem2,elem3,......)
# 特点：不可变，有序，元素的类型可以不相同，元素可以不唯一
# 注意：当需要创建只有一个元素的元组时 要加上 逗号

tuple1 = (1, 2, 2, "3", "abc", True, 8, 9)
print(tuple1, type(tuple1))

print(tuple1.index(2))
print(tuple1.count(2))
# tuple1[0] = "1" # 不能修改元组
print(tuple1[0])
# 元组也支持切片
print(tuple1[2:5:1])
tuple2 = (1)  # 实际上没有产生元组，而是创建了一个int类型的变量
print(tuple2, type(tuple2))
tuple2 = (1,)
print(tuple2, type(tuple2))

# 字典dict
# 相当于Java中的Map，有点像json
# 定义：{"k1":"v1","k2":"v2","k3":"v3",......}
# 特点：字典中的元素都是k-v格式的，key不要重复，value可以是任意类型
#       可变的，无序的，
# 查询非常快，不会随着元素的增多而变慢
# 注意：key必须是不可变的（元组、5大基本数据类型）

dict1 = {
    "k1": "v1",
    "k2": 2,
    "k3": True,
    "k4": None,
    "k5": [1, 2, 3],
    "k6": (1, 2),
    "k7": {
        "kk7": "vv7"
    }
}
print(dict1, type(dict1))

# 取元素
# 可以通过key去取出对应的value
# 当key不存在则报错
print(dict1["k1"])
print(dict1["k3"])
# print(dict1["kd3"])
# 另外一种取value的方式(推荐)
print(dict1.get("k4", "如果key不存在则返回"))
print(dict1.get("kd4", "如果key不存在则返回"))
# 改
dict1["k3"] = False
print(dict1)
# 增
dict1["newkey"] = "newValue"
print(dict1)
# 删
dict1.pop("newkey")
print(dict1)
del dict1['k7']
print(dict1)

dict2 = {
    "k1": "v1",
    True: "v4",
    False: "v5",
    1: "v2",
    0: "v3",
    2: "vv2",
    None: "none"
}
# 当字典在定义的时候如果出现了True和False以及数值型的Key
# 除零以外的整型 都等于 True，但是在dict中只有1和True会相互覆盖，0和False会相互覆盖
# 那么后面的值会覆盖前面的
print(dict2[True])
print(dict2[1])
print(dict2[False])
print(dict2[0])
print(dict2[2])
print(dict2[None])

# 集合set
# 定义：{elem1,elem2,elem3,......}
# 特点：元素是唯一的，会自动去重，元素的类型可以不相同，无序，可变的
set1 = {1, 2, 3, 3, 4, 4, 4, 1, 1, 1, 5, 6, 7, "abc", None}
print(set1, type(set1))

# print(set1[0])
set1.remove(2)
print(set1)
set1.add(7)
print(set1)

# 交 并 差
set2 = {1, 2, 3, 4, 5, 6}
set3 = {4, 5, 6, 7, 8, 9}
print(set2 & set3)  # 4,5,6
print(set2 | set3)  # 1->9
print(set2 - set3)  # {1, 2, 3}
print(set3 - set2)  # {8, 9, 7}

# enumerate 函数
# 如果想要在遍历容器的时候获取对应元素的下标则可以使用enumerate函数
print(list1)
cnt = 0
for i in list1:  # 相当于Java中的 for each
    print(cnt, i)
    cnt += 1

for i in enumerate(list1):  # 相当于Java中的 for each
    print(i)

# zip函数
key_list = ["k1", "k2", "k3"]
value_list = ["v1", "v2", "v3"]
# 将两个list压成k-v形式 形成dict
for i in zip(key_list, value_list):
    print(i)

# 格式化字符串
# 9 9 乘法表：{} * {} = {}
a = 3
b = 2
print(a, "*", b, "=", a * b)

# 定义好一个模板
str_format = "{} * {} = {}"
print(str_format.format(a, b, a * b))
# 定义好一个规则
# %d 表示一个整型
# %s 表示一个字符串
# %f 表示一个浮点
print("%d * %d = %d" % (a, b, a * b))
print("%.3f" % (1.123456))  # 保留3位小数

# range函数
# 用于生成序列
# range(起始,结束,步长)
# 生成1~10的序列
for i in range(1, 11, 1):
    print(i)

# 列表推导式
# 通过一个表达式生成列表
list1 = [str(i) for i in range(1, 11) if i % 2 == 1]
print(list1)

# 打印列表
print("|".join(list1))

# 9 9 乘法表
print("\n".join(["\t".join(["{} * {} = {}".format(i, j, i * j) for j in range(1, i + 1)]) for i in range(1, 10)]))
